
import express from 'express'
import fs from 'fs'
// import multiparty from 'multiparty'
import SparkMD5 from 'spark-md5'
const app = express.Router();
const PORT = 4000


/* -API- */
const multiparty = require('multiparty')
const uploadDir =  `${__dirname}/upload`

function handleMultiparty(req, res, temp) {
  return new Promise((resolve, reject) => {
    // multiparty 配置
    let options = {
      maxFieldsSize: 200 * 1024 * 1024 // 现在最大上传文件多大
    }
    // 
    !temp ? options.uploadDir = uploadDir : null // 配置上传文件到什么目录
    let form = new multiparty.Form(options)
    // multiparty 解析
    form.parse(req, function(err, fields, files){
      if(err) {
        res.send({
          code: 1,
          reason: err
        })
        reject(err)
        return
      }
      resolve({
        fields,
        files
      })
    })
  })
}

// 基于form-data上传数据
app.post('/single1', async (req, res) => {
  let { files } = await handleMultiparty(req, res)
  // console.log(files)
 let file = files.file[0]

 res.send({
   code: 0,
   originalFilename: file.originalFilename,
   path: file.path.replace(__dirname, `http://127.0.0.1:${PORT}`)
 })
});


// 上传base64
app.post('/single2', async (req, res) => {
  let { chunk, filename } =  req.body
  // ckunk的处理：转换为buffer
  // console.log('chunk0',chunk)
  chunk = decodeURIComponent(chunk)
  chunk = chunk.replace(/^data:image\/\w+;base64,/, '')
  // 将base64转成buffer
  chunk = Buffer.from(chunk, 'base64')
  // console.log('chunk',chunk)
  // 存储文件到服务器
  let spark = new SparkMD5.ArrayBuffer(),
      suffix = /\.([0-9A-zA-Z]+)$/.exec(filename)[1],
      path;
  //  将文件内容转成hash 
  spark.append(chunk)
  
  // console.log('spark.end()',spark.end())
  // spark.end() 可以获取hash值
  path = `${uploadDir}/${spark.end()}.${suffix}`
  fs.writeFileSync(path,chunk)
  res.send({
    code: 0,
    originalFilename: filename,
    path: path.replace(__dirname, `http://127.0.0.1:${PORT}`)
  })
})

// 切片上传 && 合并
app.post('/single3', async (req, res) => {
  let {fields, files} = await handleMultiparty(req, res, true)

  let [chunk] = files.chunk,
      [filename] = fields.filename,
      hash = /([0-9a-zA-Z]+)_\d+/.exec(filename)[1]
  //  suffix = /\.([0-9a-zA-Z]+)$/.exec(file.name)[1] 
  console.log('hash:',hash,filename)
     let path = `${uploadDir}/${hash}`;
  //  当第一次第一个切片文件上传的时会临时创建一个文件夹 
  !fs.existsSync(path) ? fs.mkdirSync(path) : null;
  path = `${path}/${filename}`
  fs.access(path, async (err) => {
    // 存在的则不再进行任何的处理
    if(!err) {
      res.send({
        code: 0,
        path: path.replace(__dirname, `http://127.0.0.1:${PORT}`)
      })
      return 
    }

    // 为了测试出效果，延迟1秒钟
    await new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve()
      },200)
    })

    // 不存在的再创建
    // 用文件流的方式进行创建
    let readStream = fs.createReadStream(chunk.path),
        writeStream = fs.createWriteStream(path)
        readStream.pipe(writeStream)
        readStream.on('end', () => {
          
          fs.unlinkSync(chunk.path) // 删除文件操作
          res.send({
            code: 0,
            path: path.replace(__dirname, `http://127.0.0.1:${PORT}`)
          })
        })
  }) 
})

// 文件传完后合并文件同时删除切片文件夹
app.get('/merge', (req, res) => {
  let {hash} = req.query
  let path = `${uploadDir}/${hash}`,
      fileList = fs.readdirSync(path),
      suffix;
      fileList.sort((a,b) => {
        let reg = /_(\d+)/
        return reg.exec(a)[1] - reg.exec(b)[1]
      }).forEach(item => {
        !suffix ? suffix = /\.([0-9a-zA-Z]+)$/.exec(item)[1] : null
        // fs.appendFileSync()方法的用途是通过异步的方法将文本内容或数据添加到文件里，如果文件不存在则会自动创建
        fs.appendFileSync(`${uploadDir}/${hash}.${suffix}`, fs.readFileSync(`${path}/${item}`))
        // 删除文件操作
        fs.unlinkSync(`${path}/${item}`)
      })
     //  rmdirSync 方法删除文件目录
      fs.rmdirSync(path)
      res.send({
        code: 0,
        path: `http: //127.0.0.1:${PORT}/upload/${hash}.${suffix}`
      })
})




module.exports = app;